// HashMap.h
#ifndef __HASHMAP_H__
#define __HASHMAP_H__

#include <tr1/unordered_map>

#include "util/List.h"
#include "util/Pool.h"
#include "util/Vector.h"

template <typename K, typename T, typename H = std::tr1::hash<K>, typename E = std::equal_to<K> >
class HashMap : public std::tr1::unordered_map <K, T, H, E, pool_allocator<T> > {
  public:
    NEW_DELETE_OPERATORS_INLINE_H(HashMap,NoSuper);
    
    HashMap () {};
    HashMap (size_t __n) : std::tr1::unordered_map<K,T,H,E,pool_allocator<T> >(__n) {};
    ~HashMap () {};

    void clear (bool deepClear=false) {
#if 0
        if (deepClear) {
            for (typename HashMap<K,T,H,E>::iterator i = this->begin(); i != this->end(); i++) {
                std::pair<K, T> pair = *i;
                delete pair.second;
            }
        }
#endif
        std::tr1::unordered_map<K,T,H,E,pool_allocator<T> >::clear();
    }

    T lookup (K k) {
        typename HashMap<K,T,H,E>::iterator i = this->find(k);
        if (i == this->end()) {
            return (T)NULL;
        }
        std::pair<K, T> pair = *i;
        return pair.second;
    }

    void add (K k, T t) {
        (*this)[k] = t;
    }

    T remove (K k) {
        typename HashMap<K,T,H,E>::iterator i = this->find(k);
        if (i == this->end()) {
            return (T)NULL;
        }
        std::pair<K, T> pair = *i;
        T t = pair.second;
        this->erase(i);
        return t;
    }

    List<T>* getList () {
        List<T>* l = new List<T>;
        for (typename HashMap<K,T,H,E>::iterator i = this->begin(); i != this->end(); i++) {
            std::pair<K, T> pair = *i;
            l->add(pair.second);
        }
        return l;
    }
    int keys (K* array) {
        int j = 0;
        for (typename HashMap<K,T,H,E>::iterator i = this->begin(); i != this->end(); i++) {
            std::pair<K, T> pair = *i;
            array[j++] = pair.first;
        }
        return j;
    }
    Vector<K>* keysVector () {
        Vector<K>* v = NEW Vector<K>;
        v->reserve(this->size());
        for (typename HashMap<K,T,H,E>::iterator i = this->begin(); i != this->end(); i++) {
            std::pair<K, T> pair = *i;
            v->push_back(pair.first);
        }
        return v;
    }
};

#endif // __HASHMAP_H__
